package com.qinggeng.project.api.controller;

import com.github.pagehelper.PageHelper;
import com.google.common.collect.Maps;
import com.qinggeng.common.constant.Constants;
import com.qinggeng.common.enums.*;
import com.qinggeng.common.utils.DateUtils;
import com.qinggeng.common.utils.StringUtils;
import com.qinggeng.framework.web.controller.BaseController;
import com.qinggeng.framework.web.domain.AjaxResult;
import com.qinggeng.project.api.dto.Draw;
import com.qinggeng.project.api.dto.DrawResult;
import com.qinggeng.project.api.dto.OrdersGiftDto;
import com.qinggeng.project.api.security.annotation.LoginRequired;
import com.qinggeng.project.api.security.utils.ApiUtils;
import com.qinggeng.project.api.utils.OrdersCheckUtils;
import com.qinggeng.project.system.domain.*;
import com.qinggeng.project.system.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

import static com.qinggeng.project.system.domain.GoodsGift.FREE_GIFT_CONFIG_KEY;
import static com.qinggeng.project.system.service.impl.GiftServiceImpl.*;

/**
 * @author smallfish
 */
@Api(tags = "抽奖模块")
@RestController
@Slf4j
@RequestMapping("${apiPath}/gift")
@CrossOrigin
public class ApiGiftController extends BaseController {

    @Autowired
    private ISysConfigService sysConfigService;
    @Autowired
    private IOrdersService ordersService;
    @Autowired
    private IGoodsGiftService goodsGiftService;
    @Autowired
    private IUserWishGiftService userWishGiftService;
    @Autowired
    private IOrdersGiftService ordersGiftService;
    @Autowired
    private IGoodsPercentService goodsPercentService;
    @Autowired
    private IAssistRecordService recordService;
    @Resource
    private DataSourceTransactionManager dataSourceTransactionManager;

    @Resource
    private TransactionDefinition transactionDefinition;
    @Autowired
    private MQSendService mqSendService;

    @Autowired
    private IGiftService giftService;
    @Autowired
    private OrdersCheckUtils ordersCheckUtils;

    @ApiOperation("抽奖规则")
    @GetMapping("/rule")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header" ,name= Constants.TOKEN,value="token标记",dataType="String")
    })
    @LoginRequired(must = false,role = ApiUtils.DEFAULT_ROLE_USER)
    public AjaxResult drawRule(){
        Map<String,Object> data =Maps.newHashMap();
        data.put("rule",sysConfigService.getConfigValue(DRAW_RULE_KEY));
        return AjaxResult.success(data);
    }

    @ApiOperation("获取抽奖次数")
    @GetMapping("/times")
    @ApiImplicitParams({
            @ApiImplicitParam(name="ordersId",value="订单ID",dataType="Long", paramType = "query",required = true),
            @ApiImplicitParam(name= Constants.TOKEN,value="token标记",dataType="String", paramType = "header",required = true)
    })
    @LoginRequired(role = ApiUtils.DEFAULT_ROLE_USER)
    public AjaxResult getDrawTimes(Long ordersId){

        //检验订单状态
        Orders orders=ordersCheckUtils.checkOrderStatus(ordersId,ApiUtils.getUserId());

        if(!giftService.getIsActive()
            ||orders.getOrdersType().equals(OrdersTypeEnum.免费送.getValue())
            ||orders.getOrdersType().equals(OrdersTypeEnum.好友助力.getValue())){
            //更改订单打印状态
            ordersService.updateOrdersPrintStatus(orders,PrintStatusEnum.不可打印.getStatus(),PrintStatusEnum.可打印.getStatus());
            return AjaxResult.success(new Draw(ordersId,0));
        }

        if(orders.getOrdersType().equals(OrdersTypeEnum.捶一捶.getValue())){
            return AjaxResult.success(new Draw(ordersId,0));
        }

        Draw draw=giftService.getDrawTimes(orders);

        if(!draw.getIsDraw()){
            ordersService.updateOrdersPrintStatus(orders,PrintStatusEnum.不可打印.getStatus(),PrintStatusEnum.可打印.getStatus());
        }
        return AjaxResult.success(draw);
    }



    @ApiOperation("结束抽奖")
    @PostMapping("/end")
    @ApiImplicitParams({
            @ApiImplicitParam(name="ordersId",value="订单ID",dataType="Long", paramType = "query",required = true),
            @ApiImplicitParam(name= Constants.TOKEN,value="token标记",dataType="String", paramType = "header",required = true)
    })
    @Transactional(rollbackFor = Exception.class)
    @LoginRequired(role = ApiUtils.DEFAULT_ROLE_USER)
    public AjaxResult end(Long ordersId){

        //检验订单状态
        Orders orders= ordersCheckUtils.checkOrderStatus(ordersId,ApiUtils.getUserId());
        //订单打印状态改为10=可打印
        ordersService.updateOrdersPrintStatus(orders,PrintStatusEnum.不可打印.getStatus(),PrintStatusEnum.可打印.getStatus());
        //返回订单详情
        return AjaxResult.success(ordersService.setOrdersInfo(orders));
    }



    @ApiOperation("奖品列表")
    @GetMapping("/list")
    @ApiImplicitParams({
            @ApiImplicitParam(name="shopId",value="商户ID",dataType="Long", paramType = "query",required = true),
            @ApiImplicitParam(name=Constants.TOKEN,value="token标记",dataType="String", paramType = "header")
    })
    @LoginRequired(must = false,role = ApiUtils.DEFAULT_ROLE_USER)
    public AjaxResult goodsGiftList(Long shopId){
        if(shopId==null){
            return AjaxResult.error("商户ID不能为空");
        }
        PageHelper.startPage(0,12);
        GoodsGift where=new GoodsGift();
        where.setShopId(shopId);
        where.setGiftType(CommonEnum.STATUS_10.getValue());  //奖品类型为10=普通奖品
        return AjaxResult.success(goodsGiftService.selectGoodsGiftDtoList(where));
    }

    @ApiOperation("加入普通奖品")
    @PostMapping("/addGoodsGift")
    @ApiImplicitParams({
            @ApiImplicitParam(name="ordersId",value="订单ID",dataType="Long", paramType = "query",required = true),
            @ApiImplicitParam(name="giftId",value="奖品ID",dataType="String", paramType = "query",required = true),
            @ApiImplicitParam(name="token",value="token标记",dataType="String", paramType = "header",required = true)
    })
    @Transactional(rollbackFor = Exception.class)
    @LoginRequired(role = ApiUtils.DEFAULT_ROLE_USER)
    public AjaxResult addGoodsGift(Long ordersId,String giftId ){

        //检查是否具备抽奖资格
        Orders orders=giftService.checkIsDraw(ordersId);

        if(StringUtils.isEmpty(giftId)){
            return AjaxResult.error("心愿清单不能为空，请选择喜欢的奖品！",ShowTypeEnum.用户.getValue());
        }
        //获取抽奖次数
        Integer drawTimes=goodsPercentService.getDrawTimes(orders);
        if(giftId.split(",").length>drawTimes){
            return AjaxResult.error("最多只可加入"+drawTimes+"个心愿清单！",ShowTypeEnum.用户.getValue());
        }
        UserWishGift userWishGift=userWishGiftService.insertUserWishGift(ordersId,giftId,drawTimes, DrawTypeEnum.普通抽奖.getType());
        return AjaxResult.success(giftService.getDrawResult(userWishGift));
    }

    @ApiOperation("加入免单奖品")
    @PostMapping("/addFreeGift")
    @ApiImplicitParams({
            @ApiImplicitParam(name="ordersId",value="订单ID",dataType="Long", paramType = "query",required = true),
            @ApiImplicitParam(name=Constants.TOKEN,value="token标记",dataType="String", paramType = "header",required = true)
    })
    @Transactional(rollbackFor = Exception.class)
    @LoginRequired(role = ApiUtils.DEFAULT_ROLE_USER)
    public AjaxResult addFreeGift(Long ordersId){
        //检查是否具备免单的抽奖资格
        giftService.checkIsFree(ordersId);
        //根据订单号查询用户心愿礼品
        UserWishGift userWishGift=userWishGiftService.selectUserWishGiftByOrdersId(ordersId);
        if(userWishGift!=null){
            return AjaxResult.error("您已加入过心愿清单，请勿重复添加！");
        }
        //免单奖品
        GoodsGift freeGift=goodsGiftService.selectGoodsGiftById(goodsGiftService.getFreeGiftId());
        if(null==freeGift){
            return AjaxResult.error("奖品ID不存在！");
        }
        //加入心愿清单（drawType: 1=免单抽奖）
        userWishGift=userWishGiftService.insertUserWishGift(ordersId,freeGift.getGiftId().toString(),1,DrawTypeEnum.免单抽奖.getType());
        //设置前台展示中奖率，与后台实际中奖率无关
        freeGift.setProbability(new BigDecimal(Math.random()*0.15+0.3).setScale(4,BigDecimal.ROUND_HALF_UP));
        Long otherGiftId=goodsGiftService.getOtherGiftId(FREE_GIFT_CONFIG_KEY);
        return AjaxResult.success(new DrawResult(1,goodsGiftService.addGoodsGiftList(freeGift,otherGiftId)));
    }

    @ApiOperation("加入好友助力奖品")
    @GetMapping("/addHelpGift")
    @ApiImplicitParams({
            @ApiImplicitParam(name="recordId",value="好友助力记录ID",dataType="Long", paramType = "query",required = true),
            @ApiImplicitParam(name=Constants.TOKEN,value="token标记",dataType="String", paramType = "header",required = true)
    })
    @LoginRequired(role = ApiUtils.DEFAULT_ROLE_USER)
    public AjaxResult addHelpGift(Long recordId){
        //好友助力记录
        AssistRecord record=recordService.checkAssistRecord(recordId);
        //助力商品
        Goods goods=recordService.checkAssistGoods(record.getGoodsId());
        //根据商品价格获取奖品及中奖率
        List<GoodsGift> gifts=goodsGiftService.selectGoodsGiftList(goods.getGroupPrice());
        return AjaxResult.success(new DrawResult(1,gifts));
    }


    @ApiOperation("助力抽奖")
    @PostMapping("/helpDraw")
    @ApiImplicitParams({
            @ApiImplicitParam(name="recordId",value="好友助力记录ID",dataType="Long", paramType = "query",required = true),
            @ApiImplicitParam(name="token",value="token标记",dataType="String", paramType = "header",required = true)
    })
    @LoginRequired(role = ApiUtils.DEFAULT_ROLE_USER)
    public AjaxResult helpDraw(Long recordId){

        long time = DateUtils.getNowDate().getTime();
        log.info("助力抽奖处理{}"+ DateUtils.getNowDate());
        //好友助力记录
        AssistRecord record=recordService.checkAssistRecord(recordId);
        //助力商品
        Goods goods=recordService.checkAssistGoods(record.getGoodsId());
        //根据商品价格获取奖品及中奖率
        List<GoodsGift> goodsGiftList=goodsGiftService.selectGoodsGiftList(goods.getGroupPrice());
        DrawResult result = new DrawResult();
        TransactionStatus transaction = null;
        try{
            //好友助力成功状态修改为3=结束
            record.setAssistSuccess(AssistStatusEnum.抽奖结束.getStatus());
            transaction = dataSourceTransactionManager.getTransaction(transactionDefinition);
            int rows=recordService.updateAssistRecord(record);
            if(rows<1){
                return AjaxResult.error("助力抽奖错误");
            }
            //中奖号码范围
            String numberRange = sysConfigService.getConfigValue(NUMBER_RANGE_KEY);
            //获取中奖号码
            Map<Integer, GoodsGift> luckyNum = giftService.getLuckyNum(goodsGiftList, numberRange);
            //产生用户抽奖号码
            Integer drawNum = (int) (Math.random() * Integer.parseInt(numberRange));
            //判断中奖结果
            result=giftService.getAssistDrawResult(record,luckyNum,drawNum);
            dataSourceTransactionManager.commit(transaction);

           log.info("耗时 ："+(DateUtils.getNowDate().getTime()-time)/1000+"s");
            return AjaxResult.success(result);
        }catch (Exception e){
            if (transaction != null){
                dataSourceTransactionManager.rollback(transaction);
            }
            log.error(e.getMessage());
            result.setIsWin(false);
            return AjaxResult.success(result);
        }
    }



    @ApiOperation("订单抽奖")
    @GetMapping("/ordersDraw")
    @ApiImplicitParams({
            @ApiImplicitParam(name="ordersId",value="订单ID",dataType="Long", paramType = "query",required = true),
            @ApiImplicitParam(name="token",value="token标记",dataType="String", paramType = "header",required = true)
    })
    @LoginRequired(role = ApiUtils.DEFAULT_ROLE_USER)
    public AjaxResult drawGift(Long ordersId){
        //检验订单是否具备抽奖资格
        Orders orders=giftService.checkIsDraw(ordersId);
        UserWishGift userWishGift=userWishGiftService.selectUserWishGiftByOrdersId(ordersId);
        if(userWishGift==null){
            return AjaxResult.error("请先加入心愿清单！",ShowTypeEnum.用户.getValue());
        }

        if(userWishGift.getDrawTimes()<1){
            return AjaxResult.error("抽奖次数已用完！",ShowTypeEnum.用户.getValue());
        }

        //获取本次抽奖的奖品
        List<GoodsGift> goodsGiftList=goodsGiftService.selectGoodsGiftList(userWishGift);
        TransactionStatus transaction = null;
        try {
            transaction = dataSourceTransactionManager.getTransaction(transactionDefinition);
            //扣除抽奖次数
            userWishGift=userWishGiftService.updateUserWishGiftDrawTimes(userWishGift);

            //中奖号码范围
            String numberRange=sysConfigService.getConfigValue(NUMBER_RANGE_KEY);
            if(giftService.checkIsReturn(orders.getCreateTime())){
                numberRange="0";
            }
            //获取中奖号码
            Map<Integer,GoodsGift> luckyNum=giftService.getLuckyNum(goodsGiftList,numberRange);
            //产生用户抽奖号码
            Integer drawNum=(int)(Math.random()* Integer.parseInt(numberRange));
            //判断中奖结果
            DrawResult result=giftService.getOrdersDrawResult(userWishGift,luckyNum,drawNum);
            dataSourceTransactionManager.commit(transaction);
            return AjaxResult.success(result);
        }catch (Exception e){
            if (transaction != null){
                dataSourceTransactionManager.rollback(transaction);
            }
            log.error(e.getMessage());
            DrawResult result=giftService.getDrawResult(userWishGift);
            result.setIsWin(false);
            return AjaxResult.success(result);
        }
    }




    @ApiOperation("领取奖品")
    @PostMapping("/pick")
    @ApiImplicitParams({
            @ApiImplicitParam(name="ordersGiftId",value="订单奖品ID",dataType="Long", paramType = "query",required = true),
            @ApiImplicitParam(name="token",value="token标记",dataType="String", paramType = "header",required = true)
    })
    @Transactional(rollbackFor = Exception.class)
    @LoginRequired(role = ApiUtils.DEFAULT_ROLE_USER)
    public AjaxResult pickGift(Long ordersGiftId){
        OrdersGift ordersGift=ordersGiftService.selectOrdersGiftByIdAndUserId(ordersGiftId,ApiUtils.getUserId());
        if(ordersGift==null){
            return AjaxResult.error("未查询到您的中奖记录！",ShowTypeEnum.用户.getValue());
        }
        //检验是否具备抽奖资格
        giftService.checkIsDraw(ordersGift.getOrdersId());
        if(ordersGift.getPickFlag().equals(CommonEnum.STATUS_20.getValue())){
            return AjaxResult.error("您已经领取过了哦，请勿重复领取！",ShowTypeEnum.用户.getValue());
        }
        ordersGift.setPickFlag(CommonEnum.STATUS_20.getValue());
        int rows=ordersGiftService.updateOrdersGift(ordersGift);
        if (rows<=0){
            return AjaxResult.error("领取失败！",ShowTypeEnum.用户.getValue());
        }
        GoodsGift goodsGift=goodsGiftService.selectGoodsGiftById(ordersGift.getGiftId());
        if(null==goodsGift) {
            return AjaxResult.error("领取的奖品不存在",ShowTypeEnum.用户.getValue());
        }
        //更新普通奖品的库存
        if(goodsGift.getGiftId().compareTo(goodsGiftService.getFreeGiftId())!=0){
            goodsGiftService.updateGoodsGiftNum(goodsGift);
            return AjaxResult.success("恭喜您领取成功！",ShowTypeEnum.用户.getValue());
        }
        //订单退款
        boolean result=ordersService.ordersRefund(ordersGift.getOrdersId(),ApiUtils.getUserId());
        if(!result){
            return AjaxResult.error("领取失败！",ShowTypeEnum.用户.getValue());
        }
        return AjaxResult.success("恭喜您领取成功！",ShowTypeEnum.用户.getValue());
    }

    @ApiOperation("中奖记录")
    @GetMapping("/record")
    @ApiImplicitParams({
            @ApiImplicitParam(name="token",value="token标记",dataType="String", paramType = "header")
    })
    @LoginRequired(must = false,role = ApiUtils.DEFAULT_ROLE_USER)
    public AjaxResult record(){
        List<OrdersGiftDto> ordersGiftList=ordersGiftService.selectOrdersGiftDtoList(null);
        return AjaxResult.success(ordersGiftList);
    }

    @GetMapping("/outTime")
    @ApiOperation("抽奖超时时间")
    @ApiImplicitParams({
            @ApiImplicitParam(name="ordersId",value="订单ID",dataType="Long", paramType = "query",required = true),
            @ApiImplicitParam(name="token",value="token标记",dataType="String", paramType = "header")
    })
    @LoginRequired(must = false,role = ApiUtils.DEFAULT_ROLE_USER)
    public AjaxResult outTime(Long ordersId){
        //检验订单是否具备抽奖资格
        Orders orders=giftService.checkIsDraw(ordersId);
        String outTime=sysConfigService.getConfigValue(OUT_PRINT_TIME_KEY);
        Calendar printTime=Calendar.getInstance();
        printTime.setTime(orders.getPayTime());
        printTime.add(Calendar.MINUTE,Integer.parseInt(outTime));
        if(printTime.before(DateUtils.getNowDate())){
            return AjaxResult.error("抽奖已超时！",ShowTypeEnum.用户.getValue());
        }
        Map<String,Object> data=Maps.newHashMap();
        data.put("outTime",printTime.getTime().getTime());
        return AjaxResult.success(data);

    }


}
